#pragma once
/// MapController responsible for storing, changing, and drawing data from files
#include <iostream>
#include <fstream>
#include <Windows.h>
#include <cmath>
#include <ctime>
using namespace std ;

#define MINE	0
#define HIDDEN	9
#define NOTHING 10
#define FLAGGED	11

#define SIZE_EASY	9
#define SIZE_NORMAL	16

#define SCREEN_WIDTH	1024
#define SCREEN_HEIGHT	600

class Map
{
private:
	//2D vector struct
	float m_offset ;

	//2D map data
	char ** m_map ;

	bool ** m_hidden ;

	bool ** m_flagged ;

	//width and height of the map
	int m_width ;
	int m_height ;
	int m_mineAmount, m_flagsAvailable, m_safeTiles ;

	//define file seek offsets and spawn position
	#define FILE_OFFSET_LARGE	7
	#define FILE_OFFSET_SMALL	5

public:
	//Constructor
	Map() ;

	//Copy Constructor
	Map( Map & a_original ) ;

	//Creates a new dynamically allocated 2D array of ints
	static char ** Map::new2Dmap( int const & h, int const & w )
	{
		char ** newMap = new char * [h] ;
		for( int row = 0; row < h; ++row )
			newMap[row] = new char[w] ;
		return newMap ;
	}

	//Deletes the 2D int array
	static void Map::delete2Dmap( char ** map, int const & h )
	{
		if( map )
		{
			for( int row = 0; row < h; ++row )
				delete [] map[row] ;
			delete map ;
			map = 0 ;
		}
	}

	//Loads the source file of the map, returns false if the file is not found
	bool loadFile( char * filename ) ;

	//returns if tile is hidden
	bool isHidden(int x, int y) {return m_hidden[y][x];}

	//checks if tile was flagged by player
	bool isFlagged(int x, int y) {return m_flagged[y][x] ;}

	//checks if player has anymore flags
	bool canFlag() { return m_flagsAvailable > 0 ; }

	//checks the map if any mines have been revealed
	bool lossCondition( ) ;

	//checks if player revealed all of the safe tiles
	bool winCondition() { return m_safeTiles <= 0 ; }

	//Gets the Width or Height of the map
	int getWidth( ) { return m_width ; }
	int getHeight( ) { return m_height ; }

	//get the amount of flags used
	int getFlags( ) { return m_mineAmount - m_flagsAvailable ; }

	//gets current amount of mines on map
	int getMines( ) { return m_mineAmount ; }

	//gets the offset of the map
	float getOffset( ) { return m_offset ; }

	//used to find the tag for sprite rendering
	int getID(int x, int y) ;

	//gets the specific map data
	char get( int x, int y ) ;

	//controls how the map generates mines
	void generateMap( ) ;

	//resets the map
	void clearMap( ) ;

	//functions that reveal hidden tiles
	void reveal(int x, int y) ;
	void revealAdj(int x, int y) ;
	void revealMines( ) ;

	//searches for the tile's neighbors
	void searchAdj( int x, int y ) ;

	//controls how the tiles are flagged when right-clicked
	void flag(int x, int y) { m_flagged[y][x] = true ; m_flagsAvailable-- ; }
	void unflag(int x, int y) { m_flagged[y][x] = false ; m_flagsAvailable++ ;}

	//deletes the 2D map data safely
	void release( ) ;

	//destructor calls the release function for safe deletion
	~Map() {release( ) ;}
} ;